package com.ldzy.webase.controller;

import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.ldzy.webase.annotation.PassToken;
import com.ldzy.webase.annotation.UserLoginToken;
import com.ldzy.webase.exception.ExceptionResponse;
import com.ldzy.webase.exception.ExceptionResponseCode;
import com.ldzy.webase.service.UserService;
import com.ldzy.webase.utils.Response;
import com.ldzy.webase.utils.ResponseCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author ：Lq
 * @version ：1.0
 * @date ：2022/10/25 12:16
 * @description ：公共接口
 */

@RestController
@ResponseBody
@RequestMapping("/common")
public class CommonController {
    @Autowired
    UserService userService; //用户接口
    @Autowired
    private JavaMailSender mailSender; // 收发邮件

    /**
     * @邮箱发送方账户信息
     */
    @Value("${spring.mail.username}")
    private String from;

    /**
     * @头像图片路径
     */
    @Value("${file.avatarImage.resource-path}")
    private String avatarImageResourcePath; // 头像,映射路径
    @Value("${file.avatarImage.upload-path}")
    private String avatarImageUploadPath; // 头像,上传路径

    /**
     * @首页资讯图片路径
     */
    @Value("${file.pressImage.resource-path}")
    private String pressImageResourcePath; // 首页资讯图片,映射路径
    @Value("${file.pressImage.upload-path}")
    private String pressImageUploadPath; // 首页资讯图片,上传路径

    /**
     * @轮播图图片路径
     */
    @Value("${file.slideshowImage.resource-path}")
    private String slideshowImageResourcePath; // 轮播图图片,映射路径
    @Value("${file.slideshowImage.upload-path}")
    private String slideshowImageUploadPath; // 轮播图图片,上传路径

    /**
     * @咨询分类封面图片路径
     */
    @Value("${file.consultImage.resource-path}")
    private String consultImageResourcePath; // 咨询分类封面图片,映射路径
    @Value("${file.consultImage.upload-path}")
    private String consultImageUploadPath; // 咨询分类封面图片,上传路径

    /**
     * @场馆预约封面图片路径
     */
    @Value("${file.sportsImage.resource-path}")
    private String sportsImageResourcePath; // 咨询分类封面图片,映射路径
    @Value("${file.sportsImage.upload-path}")
    private String sportsImageUploadPath; // 咨询分类封面图片,上传路径

    /**
     * @今日菜系图片路径
     */
    @Value("${file.todayCuisineImage.resource-path}")
    private String todayCuisineImageResourcePath; // 咨询分类封面图片,映射路径
    @Value("${file.todayCuisineImage.upload-path}")
    private String todayCuisineImageUploadPath; // 咨询分类封面图片,上传路径

    /**
     * @param type 需指定上传的用途、类型：
     *             1.【avatarImage 头像】 2.【pressImage 首页资讯图片】 3.【slideshowImage 轮播图图片】
     *             4.【consultImage 咨询分类封面图片】 5.【sportsImage 场馆预约封面】 6.【todayCuisineImage 今日菜系封面图片】
     * @author ：Lq
     * @date ：2022/10/23 15:28
     * @description ：上传文件、图片
     */
    //下面是编写接口名和请求方式
    @PostMapping(value = "/upload")
    @UserLoginToken
    public Response upload(MultipartRequest request, @RequestParam(value = "num", defaultValue = "1") Integer num, @RequestParam(value = "type", defaultValue = "avatarImage", required = false) String type) throws IllegalStateException, IOException {
        // 多文件上传使用这个，具体查看网页收藏夹
        List<MultipartFile> files = new ArrayList<>();

        for (int i = 0; i < num; i++) {
            MultipartFile file = request.getFile("files" + i);
            System.out.println(file.getOriginalFilename());
            files.add(request.getFile("files" + i));
        }

        String fileResourcePath = pressImageResourcePath; // 文件/图片映射路径
        String fileUploadPath = pressImageUploadPath; // 文件/图片上传路径

        if (type.equals("avatarImage")) {
            // 需要上传到头像路径
            fileResourcePath = avatarImageResourcePath;
            fileUploadPath = avatarImageUploadPath;
        } else if (type.equals("pressImage")) {
            // 需要上传到首页资讯图片路径
            fileResourcePath = pressImageResourcePath;
            fileUploadPath = pressImageUploadPath;
        } else if (type.equals("slideshowImage")) {
            // 需要上传到轮播图图片路径
            fileResourcePath = slideshowImageResourcePath;
            fileUploadPath = slideshowImageUploadPath;
        } else if (type.equals("consultImage")) {
            // 需要上传到咨询分类封面图片路径
            fileResourcePath = consultImageResourcePath;
            fileUploadPath = consultImageUploadPath;
        } else if (type.equals("sportsImage")) {
            // 需要上传到场馆预约封面路径
            fileResourcePath = sportsImageResourcePath;
            fileUploadPath = sportsImageUploadPath;
        }else if(type.equals("todayCuisineImage")){
            // 需要上传到今日菜系封面图片路径
            fileResourcePath = todayCuisineImageResourcePath;
            fileUploadPath = todayCuisineImageUploadPath;
        }

//        System.out.println(type);

        Map<String, Object> map = new HashMap();
        // 如果是多文件，需要拼接，多个其中用;分割
        String imgUrls = "";

        for (int i = 0; i < files.size(); i++) {
            // 获取上传的文件名
            String fileName = files.get(i).getOriginalFilename();

            // 获得文件后缀名例如.png
            String lastName = fileName.substring(fileName.lastIndexOf("."));

            //拼接图片名称，采用uuid随机数，保证每个图片的图片名称不同
            UUID uuid = UUID.randomUUID();
            // 生成新的文件名 (拼接后的url，替换掉原有的图片名称，改成uuid 16位随机数)
            String newFileName = uuid + lastName;

            // 将文件路径与新的文件名拼接起来, 这是在静态资源中配置的本地绝对路径
            File newPath = new File(fileUploadPath, newFileName);

            // 判断本地路径文件夹是否存在若不存在则逐级创建
            if (!newPath.exists()) {
                newPath.mkdirs();
            }

//            try {
            // 将文件保存在本地，服务器映射地址为：
            // ip地址 http://localhost
            // 端口号 :8088
            // 静态资源的映射路径 http://localhost/8088/upload/file/xxx.jpg
            // 文件名 newFileName
            files.get(i).transferTo(newPath);
            System.out.println("图片已上传，路径为：" + newPath);

            // 可多文件上传，也可单文件
            if (i == files.size() - 1) {
                // 单文件或者多文件的最后一位不需要拼接
                imgUrls += fileResourcePath + newFileName;
            } else {
                // 多文件之间每个路径之间用;拼接
                imgUrls += fileResourcePath + newFileName + ";";
            }
//            } catch (IOException e) {
//                e.printStackTrace();
//                throw ExceptionResponse.build(ExceptionResponseCode.ERROR_UPLOAD); // (401, "上传失败，预期外的错误")
//            }
        }

        if (files.size() > 1) {
            map.put("fileName", "多文件上传"); // 文件名
        } else {
            map.put("fileName", "单文件上传"); // 文件名
        }

        map.put("url", imgUrls); // 文件访问地址

        return Response.build(ResponseCode.SUCCESS, map);
    }


    /**
     * @param type 1. emailBinding 邮箱绑定验证码 2. forgetPwd 重置密码验证码
     * @author ：Lq
     * @version ：1.0
     * @date ：2022/11/13 19:26
     * @description ：发送验证码到用户邮箱
     */
    @GetMapping("/email")
    @PassToken
    public Response ToEmail(@RequestParam(value = "email") String email, @RequestParam(value = "type", defaultValue = "emailBinding") String type, HttpServletRequest request) throws MessagingException {
        if (email == null || email.equals("")) {
            throw ExceptionResponse.build(ExceptionResponseCode.ERROR_NOT_EMAIL); // (401, "邮件发送失败，预料外的错误")
        }
        // 从请求头中取出token
        String token = request.getHeader("Authorization");
        int uid;
        if (token == null || token.equals("")) {
            // 根据邮箱获取用户uid
            uid = Integer.parseInt(userService.getUidByEmail(email));
        } else {
            // 从token中取出的uid，不需要担心是否为null，因为@UserLoginToken注解已经验证过了
            uid = Integer.parseInt(JWT.decode(token).getAudience().get(0));
        }

        //生成4位数随机验证码
        int randomCode = (int) (Math.random() * 9000 + 1000);


        // 创建一个邮箱对象
        // 创建可以编写HTML邮件消息的对象
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper minehelper = new MimeMessageHelper(message, true);
        //谁发的
        minehelper.setFrom("校园生活服务平台开发者" + '<' + from + '>');
        //谁要接收
        minehelper.setTo(email);
        //邮件标题
        minehelper.setSubject("校园生活服务平台");
        //邮件内容
        if (type.equals("emailBinding")) {
            // 邮箱绑定验证码
            minehelper.setText("<html><body>" +
                    "感谢您使用校园生活服务平台！验证码：" + randomCode +
                    "<br>如果您没有要求更改或绑定邮箱，请忽略此邮件。" +
                    "</body></html>", true);
        } else if (type.equals("forgetPwd")) {
            // 重置密码验证码
            minehelper.setText("<html><body>" +
                    "感谢您使用校园生活服务平台！验证码：" + randomCode +
                    "<br>如果您没有要求重置密码，请忽略此邮件。" +
                    "</body></html>", true);
        }
        try {
            mailSender.send(message); // 调用发送邮件的方法
        } catch (MailException e) {
            e.printStackTrace();
            throw ExceptionResponse.build(ExceptionResponseCode.ERROR_NOT_EMAIL); // (401, "邮件发送失败，预料外的错误")
        }

        // 将验证码保存在session中
        // uid+emailBinding作为键不重复，验证码作为值
        HttpSession session = request.getSession();
        if (type.equals("emailBinding")) {
            // 保存邮箱绑定验证码，默认30分钟后失效
            session.setAttribute(uid + "emailBinding", randomCode);
            session.setAttribute(uid + "emailBindingName", email);
        } else if (type.equals("forgetPwd")) {
            // 保存重置密码验证码，默认30分钟后失效
            session.setAttribute(uid + "forgetPwd", randomCode);
            session.setAttribute(uid + "forgetPwdName", email);
        }

        // 返回成功消息
        return Response.build(ResponseCode.SUCCESS);
    }
}
